#!/usr/bin/python
"""
Unit test for the Ignatz db model classes.

Copyright 2008 Ryan Barrett
"""

__author__ = 'Ryan Barrett <ignatz at ryanb dot org>'
__url__ = 'http://code.google.com/p/ignatz/'

import datetime
import unittest

from google.appengine.ext import db

from base_test import BaseTest
from models import Goal, Milestone


class GoalTest(BaseTest):
  """Tests the Goal model class."""

  def test_put_get_and_query(self):
    g = Goal(name='foo')

    m1 = MilestoneTest.make_milestone()
    m2 = MilestoneTest.make_milestone()
    m2.name = 'm2'
    g.milestones = [m1, m2]

    key = g.put()
    got = Goal.get(key)
    self.assertEqual([m1, m2], got.milestones)

    got = Goal.all().get()
    self.assertEqual([m1, m2], got.milestones)

  def test_validate(self):
    g = Goal(name='foo')

    for bad_value in ('not a list', (1, 2), {1: 2}, db.Blob('abc'),
                      Milestone(), g):
      g.milestones = bad_value
      self.assertRaises(AssertionError, g.put)
      if not isinstance(bad_value, Milestone):
        g.milestones = [bad_value]
        self.assertRaises(AssertionError, g.put)


class MilestoneTest(BaseTest):
  """Tests the Milestone class."""

  now = datetime.datetime.now()

  def setUp(self):
    BaseTest.setUp(self)

  @classmethod
  def make_milestone(cls, **kwds):
    # defaults
    attrs = {
      'name': 'foo',
      'description': 'bar',
      'due': cls.now,
      }
    attrs.update(kwds)
    return Milestone(**attrs)
  

  def test_constructor(self):
    m = MilestoneTest.make_milestone()
    self.assertEqual('foo', m.name)
    self.assertEqual('bar', m.description)
    self.assertEqual(self.now, m.due)

  def test_set_attributes(self):
    m = Milestone()
    m.name = 'foo'
    self.assertEqual('foo', m.name)

    m.name = u'foo'
    self.assertEqual(u'foo', m.name)

    m.description = 'bar'
    self.assertEqual('bar', m.description)

    m.due = self.now
    self.assertEqual(self.now, m.due)

  def test_set_bad_attributes(self):
    m = Milestone()
    self.assertRaises(AssertionError, setattr, m, 'name', 123)
    self.assertRaises(AssertionError, setattr, m, 'description', {})
    self.assertRaises(AssertionError, setattr, m, 'due', 'soon')

  def test_eq(self):
    make_milestone = MilestoneTest.make_milestone
    m = make_milestone()

    self.assertEqual(m, m)
    self.assertEqual(m, make_milestone())
    self.assertNotEqual(m, make_milestone(name='not m'))
    self.assertNotEqual(m, make_milestone(description='not m'))
    self.assertNotEqual(m, make_milestone(due=datetime.datetime(1999, 12, 31)))


if __name__ == '__main__':
  unittest.main()
